﻿package component.formula.function;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import component.formula.exception.FormulaException;
import component.formula.operation.Operation;
import component.formula.operation.OperationFactory;
import component.formula.util.CalculateUtil;


//简单的逻辑运算,没有括号
public class If extends AbstractFunction{
	
	public static void main(String[] args) throws FormulaException {
		String str = "";
		str = "1>=1 && 2>=3 || 1>1";
		//str = "本科=本科 && 本科=专科";
		
		//str = " 1=2 && 3=4 ";
		//str = " -1=2 && 3=4 || true ";
		//str = "-2=-2";
		//str = "200>0  &&  200<500 && 1=2 ";
		
		str = "-1300>0 && -1300<=500";
		AbstractFunction fun = new If();
		System.out.println(fun.calculate(str));
	}
	
	public static Map logicMap = new HashMap();//逻辑运算符号
	public static Map compareMap = new HashMap();//比较运算符号
	static{
		try {
			logicMap.put("&", OperationFactory.getOperation("&"));
			logicMap.put("&&", OperationFactory.getOperation("&&"));
			logicMap.put("|", OperationFactory.getOperation("|"));
			logicMap.put("||", OperationFactory.getOperation("||"));
			
			compareMap.put("=", OperationFactory.getOperation("="));
			compareMap.put("==", OperationFactory.getOperation("=="));
			compareMap.put("!=", OperationFactory.getOperation("!="));
			compareMap.put(">", OperationFactory.getOperation(">"));
			compareMap.put(">=", OperationFactory.getOperation(">="));
			compareMap.put("<", OperationFactory.getOperation("<"));
			compareMap.put("<=", OperationFactory.getOperation("<="));
		} catch (FormulaException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public Object calculate(String expression) throws FormulaException {
		String[] paraArr = expression.split(",");
		if(paraArr.length==1){ // if() 返回boolean值
			return calculateLogic(paraArr[0]);
		}
		AbstractFunction fun = (AbstractFunction)FunctionLib.funClassMap.get("sum");
		String ifValue = String.valueOf(calculateLogic(paraArr[0]));
		
		// if(条件,true返回的值,false返回的值)
		if("true".equals(ifValue)){ 
			return fun.calculate(paraArr[1]);
		}else if(paraArr.length>=3){
			return fun.calculate(paraArr[2]);
		}else{
			//throw new FormulaException("if函数错误：if(" + expression + ")");
			//没有第三个参数返回false
			return "false";
		}
	}
	
	//计算逻辑运算
	public Object calculateLogic(String expression) throws FormulaException {
		String compareExp = "";
		String logicExp = "";
		for(int i=0;i<expression.length();i++){
			char c = expression.charAt(i);
			if(c!=' ' && i<expression.length()-1){
				char nextC = expression.charAt(i+1);
				String str = String.valueOf(c);
				String str2 = str+String.valueOf(nextC);
				//如果遇到逻辑操作符号就计算前面的比较操作
				if(logicMap.get(str)!=null || logicMap.get(str2)!=null){
					Object value = this.calculateCompare(compareExp);
					logicExp += value + str;
					if(logicMap.get(str2)!=null){
						logicExp += String.valueOf(nextC);
						i++;
					}
					compareExp = "";
				}else{//不是逻辑操作符号
					compareExp += c;
				}
			}else{
				compareExp += c;
			}
		}
		Object value = this.calculateCompare(compareExp);
		logicExp += value;
		FormulaException.debug("逻辑表达式:"+logicExp);
		
		if(CalculateUtil.isBoolean(logicExp.trim())) {
			return String.valueOf(CalculateUtil.getBoolean(logicExp.trim()));
		}
		//计算逻辑运算
		String temp = "";
		LinkedList data = new LinkedList();
		LinkedList token = new LinkedList();
		Operation operator = null;
		String currentValue = null;
		for(int i=0;i<logicExp.length();i++){
			char c = logicExp.charAt(i);
			if(c!=' ' && i<logicExp.length()-1){
				char nextC = logicExp.charAt(i+1);
				String str = String.valueOf(c);
				String str2 = str+String.valueOf(nextC);
				//如果遇到逻辑操作符号就计算前面的逻辑操作
				Object operator1 = logicMap.get(str);
				Object operator2 = logicMap.get(str2);
				if(operator2!=null){
					operator = (Operation)operator2;i++;
				}else if(operator1!=null){
					operator = (Operation)operator1;
				}
				if(operator!=null){
					if(!token.isEmpty()){//计算
						Operation currentOper = (Operation)token.removeFirst();
						String data1 = (String)data.removeFirst();
						currentValue = String.valueOf(currentOper.calculate(data1, temp));
						data.addFirst(currentValue);
						token.addFirst(operator);
						temp="";
						operator = null;
						
					}else{
						data.add(temp);
						token.add(operator);
						temp="";
						operator = null;
					}
				}else{
					temp += c;
				}
			}else{
				temp += c;
			}
		}
		if(!token.isEmpty()){//计算
			Operation currentOper = (Operation)token.removeFirst();
			String data1 = (String)data.removeFirst();
			currentValue = String.valueOf(currentOper.calculate(data1, temp));
			data.addFirst(currentValue);
		}
		return currentValue;
	}
	
	//计算比较运算
	public Object calculateCompare(String expression) throws FormulaException {
		if(CalculateUtil.isBoolean(expression.trim())) {
			return String.valueOf(CalculateUtil.getBoolean(expression.trim()));
		}
		String token = "";
		Operation operator = null;
		for(int i=0;i<expression.length();i++){
			char c = expression.charAt(i);
			if(c!=' '){
				char nextC = expression.charAt(i+1);
				String str = String.valueOf(c);
				String str2 = str+String.valueOf(nextC);
				Object operator1 = compareMap.get(str);
				Object operator2 = compareMap.get(str2);
				if(operator2!=null){
					operator = (Operation)operator2;
					token = str2;
				}else if(operator1!=null){
					operator = (Operation)operator1;
					token = str;
				}
				if(operator!=null){
					String[] exp = expression.split(token);
					return operator.calculate(exp[0].trim(), exp[1].trim());
				}
			}
		}
		return null;
	}
	
}
